package cn.imvc.app.models;

import org.hibernate.StaleObjectStateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import cn.imvc.app.commons.SystemConfig;
import cn.imvc.app.entities.Account;
import cn.imvc.app.entities.Member;
import cn.imvc.app.repositories.AccountRepository;
import cn.imvc.util.AES;

@Service
public class AccountModelImpl implements AccountModel {

	@Autowired
	private AccountRepository accountRepository;
	@Autowired
	SystemConfig systemConfig;
	@Autowired
	private ApplicationContext applicationContext;
	@Autowired
	private MemberModel memberModel;
	@Autowired
	private FundFlowModel fundFlowModel;


	public void retrySaveAccount(Integer accountId, Integer money,Integer commissions,Integer points) {
		Account account = accountRepository.getOne(accountId);
		checkAccount(account);		
		try {
			account.setPurse(account.getPurse() + money);
			account.setCommissions(account.getCommissions() + commissions);
			account.setPoints(account.getPoints()+points);
			String content=account.getPurse()+","+account.getCommissions()+","+account.getPoints();
			account.setVerify(AES.encrypt(content, systemConfig.getAESPassword()));
			accountRepository.save(account);		
		} catch (StaleObjectStateException e) {
			applicationContext.getBean(AccountModel.class).retrySaveAccount(accountId, money,commissions,points);
		}
	}

	public void checkAccount (Account account) {
		String content=account.getPurse()+","+account.getCommissions()+","+account.getPoints();
		if(!AES.encrypt(content, systemConfig.getAESPassword()).equals(account.getVerify())||account.getIsLocked()==1){
			throw new RuntimeException();			
		};
	}

	public void retryRefundAccount(Integer memberId, Integer money, Byte type,String code) {
		Member member = memberModel.getOne(memberId);
		Account account = member.getAccount();
		checkAccount(account);
		try {
			account.setPurse(account.getPurse() + money);
			account.setCommissions(account.getCommissions() + 0);
			account.setPoints(account.getPoints()+0);
			String content=account.getPurse()+","+account.getCommissions()+","+account.getPoints();
			account.setVerify(AES.encrypt(content, systemConfig.getAESPassword()));
			accountRepository.save(account);	
			fundFlowModel.saveFundFlow(member, money, code, type);
		} catch (StaleObjectStateException e) {
			applicationContext.getBean(AccountModel.class).retryRefundAccount(memberId, money,type,code);
		}
	}

	public Account getOne(int id) {
		return accountRepository.getOne(id);
	}

	public void update(Account account) {
		accountRepository.saveAndFlush(account);
	}
}
